#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author:zhengxin
@file: 08_Pandas_CommonFunctions.py
@time: 2025/1/22  10:50
# @describe: Pandas 常用函数
"""
import json

import pandas as pd

""" 读取数据 """
# 从 CSV 文件中读取数据
df = pd.read_csv("data/nba.csv")

# 从 Excel 文件中读取数据
df = pd.read_excel("data/output.xlsx")

# 从 SQL 数据库中读取数据
import sqlite3
coon = sqlite3.connect("data/database.db")
df = pd.read_sql("select * from table_name", coon)


# 从 JSON 字符串中读取数据
json_string = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_string)  # 将 JSON 字符串转换为 Python 字典
df = pd.DataFrame([data], index=[0])  # 创建一个包含单个字典的列表，并指定索引为 0
print(df)

# 从 HTML 页面中读取数据
url = 'https://www.runoob.com'
try:
    dfs = pd.read_html(url)
    # 检查是否成功读取到表格
    if dfs:
        # 选择第一个数据框（即列表中的第一个元素）
        df = dfs[0]
        # 打印DataFrame
        print(df)
    else:
        print("未从网页中找到任何表格。")
except ValueError as er:
    print("读取失败", er)




""" 查看数据 """
import pandas as pd
data = [
    {"name": "Google", "likes": 25, "url": "https://www.google.com"},
    {"name": "Runoob", "likes": 30, "url": "https://www.runoob.com"},
    {"name": "Taobao", "likes": 35, "url": "https://www.taobao.com"}
]
df = pd.DataFrame(data)
# 显示前五行数据
df.head()

# 显示后五行数据
df.tail()

# 显示数据信息
df.info()

# 显示基本统计信息
df.describe()

# 显示数据的行数和列数
df.shape




""" 数据清洗 """
# 删除包含缺失值的行或列
df.dropna()

# 将缺失值替换为指定的值
df.fillna(0)

# 将指定值替换为新值
df.replace('Google', 'Google1', inplace=True)
print("将指定值替换为新值: ", df.to_string())

# 检查是否有重复的数据
df.duplicated()

# 删除重复的数据
df.drop_duplicates()
print("--"*40)




""" 数据选择和切片 """
# 选择指定的列
df = df['name']
print(df)

# 通过标签选择数据
data = [
    {"name": "Google", "likes": 25, "url": "https://www.google.com"},
    {"name": "Runoob", "likes": 40, "url": "https://www.runoob.com"},
    {"name": "Taobao", "likes": 35, "url": "https://www.taobao.com"}
]
df = pd.DataFrame(data)
df = df.loc[1, "likes"]
print(df)

# 通过位置选择数据
df = pd.DataFrame(data)
df = df.iloc[2, 2]
print(df)


# 选择指定的列
df = pd.DataFrame(data)
df1 = df.filter(items=["name", "likes"])
print(df1)

# 选择列名匹配正则表达式的列
df = pd.DataFrame(data)
df2 = df.filter(regex="na")
print(df2)


# 随机选择 N 行数据
df = pd.DataFrame(data)
df3 = df.sample(n=2, replace=True)
print(df3)



""" 数据排序 """
df = pd.DataFrame(data)
# 按照指定列的值排序
df4 = df.sort_values("likes")
print(df4)

# 按照多个列的值排序
df = pd.DataFrame(data)
# ascending -升序排序（True），降序排序（False
df5 = df.sort_values(["name", "likes"], ascending=[False, True])
print("按照多个列的值排序:", df5)

# 按照索引排序
df = pd.DataFrame(data)
df6 = df.sort_index()
print(df6)





""" 数据分组和聚合 """
df = pd.DataFrame(data)
# 按照指定列进行分组
df7 = df.groupby("likes")
print("按照指定列进行分组", df7)

df8 = df7.aggregate('likes').describe()
print("对分组后的数据进行聚合操作", df8)

import numpy as np
data = {
    'likes': [10, 20, 10, 30, 20, 30],
    'column_name': ['A', 'B', 'A', 'B', 'A', 'B'],
    'value': [5, 10, 15, 20, 25, 30]
}
df = pd.DataFrame(data)

# 创建透视表
df9 = df.pivot_table(values="value", index="likes", columns='column_name', aggfunc='sum')
print("生成透视表", "\n",  df9)





""" 数据合并 """
data = {
    'likes': [10, 20, 10, 30, 20, 30],
    'column_name': ['A', 'B', 'A', 'B', 'A', 'B'],
    'value': [5, 10, 15, 20, 25, 30]
}

data1 = {
    'likes': [10, 20, 10, 30, 20, 30],
    'column_name1': ['A', 'B', 'A', 'B', 'A', 'B'],
    'value1': [5, 10, 15, 20, 25, 30]
}
df = pd.DataFrame(data)
df1 = pd.DataFrame(data1)
df10 = pd.concat([df, df1])
print("将多个数据框按照行或列进行合并", "\n", df10)

df11 = pd.merge(df, df1, on="likes")
print("按照指定列将两个数据框进行合并","\n", df11)






""" 数据选择和过滤 / 数据统计和描述 """
import pandas as pd

# 读取json 数据
df = pd.read_json("data/common_functions/data.json")
print(df)

# 删除缺失值
df1 = df.dropna()
print(df1)

# 用指定的值填充缺失值
df = df.fillna({"age": 0, "score": 0})
print(df)

# 重命名列名
df = df.rename(columns={'name': '姓名', 'age': '年龄', 'gender': '性别', 'score': '成绩'})
print(df)

# 按年龄排序
df = df.sort_values(by="年龄", ascending=False)
print(df)

# 按性别分组并计算平均年龄和成绩
grouped = df.groupby("性别").agg({"年龄": "mean", "成绩": "mean"})
print(grouped)


# 选择成绩大于等于90的行，并只保留姓名和成绩两列
df = df.loc[df['成绩'] >= 90, ['姓名', '成绩']]
print(df)

# 计算每列的基本统计信息
stats = df.describe()
print(stats)

# 计算每列的平均值 -- 忽略非数值列而不做任何处理
df = pd.read_json("data/common_functions/data.json")
mean = df.mean(numeric_only=True)
print("平均值：", mean)

# 计算每列的中位数
median = df.median(numeric_only=True)
print("中位数:", median)

# 计算每列的众数
mode = df.mode()
print("众数:", mode)

# 计算每列非缺失值的数量
count = df.count()
print("每列非缺失值的数量", count)








